package com.iss.apartmentmanage.config.security;

import com.iss.apartmentmanage.service.impl.MyUserDetailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.cors.CorsUtils;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    SelfAuthenticationSuccessHandler authenticationSuccessHandler;//成功
    @Autowired
    SelfAuthenticationFailureHandler authenticationFailureHandler;//失败
    @Autowired
    MyUserDetailService myUserDetailService;
    @Autowired
    SelfAuthenticationProvider provider; // 自定义安全认证
    @Autowired
    SelfAuthenticationEntryPoint selfAuthenticationEntryPoint;//未登陆
    @Autowired
    SelfLogoutSuccessHandler logoutSuccessHandler;//退出登陆
    @Autowired
    SelfAccessDeniedHandler accessDeniedHandler;



    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//         加入自定义的安全认证
//         auth.authenticationProvider(provider);
//
//         如果没有定义provider，一定要配置这个，直接走UserDetail去验证
       auth.userDetailsService(myUserDetailService).passwordEncoder(passwordEncoder());
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and().csrf().disable()
                .authenticationProvider(provider)
        //开始拦截
                .authorizeRequests()
                .antMatchers("/home").hasAnyAuthority("home");
        //开启登录
        http
                .formLogin()
                .loginProcessingUrl("/admin/login").permitAll()//不需要在controller里面写实际路径，表示在前端输入/doLogin 就执行登陆验证
                .successHandler(authenticationSuccessHandler) // 登录成功
                .failureHandler(authenticationFailureHandler).and() // 登录失败
                .exceptionHandling()
                .authenticationEntryPoint(selfAuthenticationEntryPoint)//未登陆
                .accessDeniedHandler(accessDeniedHandler); // 无权访问 JSON 格式的数据

        //登出
        http
                .logout()
                .logoutSuccessHandler(logoutSuccessHandler)
                .permitAll();


        //让Spring security 放行所有preflight request（cors 预检请求）
        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = http.authorizeRequests();
        registry.requestMatchers(CorsUtils::isPreFlightRequest).permitAll();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder(11);
    }


}
